package com.moyq5.wifi.joystick.worker;

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

import com.moyq5.wifi.joystick.Console;
import com.moyq5.wifi.joystick.ConsoleFactory;
import com.moyq5.wifi.joystick.NettyServerChannelFactory;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;


/**
 * Netty服务
 * @author mo_yq5
 */
public class NettyServerWorker extends Worker {
    private static final Console console = ConsoleFactory.get(NettyServerWorker.class);
    private static final int PORT = 8080;
    private static final EventLoopGroup bossGroup = new NioEventLoopGroup();
    private static final EventLoopGroup workerGroup = new NioEventLoopGroup();
    private static final ServerBootstrap bootstrap = new ServerBootstrap();

    private static ChannelFuture closeFuture;

    static {
        bootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.TCP_NODELAY, true)
                .option(ChannelOption.TCP_FASTOPEN, 5)
                .option(ChannelOption.SO_BACKLOG, 128)
                .option(ChannelOption.SO_TIMEOUT, 5)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childOption(ChannelOption.SO_TIMEOUT, 5)
                .childOption(ChannelOption.SO_REUSEADDR, true)
                .childOption(ChannelOption.CONNECT_TIMEOUT_MILLIS,1000)
                .childOption(ChannelOption.ALLOW_HALF_CLOSURE, false)
                .childHandler(NettyServerChannelFactory.getInitialize());
    }

    public NettyServerWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        if (null != closeFuture && !closeFuture.isDone()) {
            return Result.success();
        }
        String host = getInputData().getString("host");

        console.info("Netty 服务启动：%s %d", host, PORT);
        ChannelFuture channelFuture = bootstrap.bind(PORT);// host,
        channelFuture.addListener(future -> {
            if (future.isSuccess()) {
                console.info("Netty 服务启动，成功：%s %d", host, PORT);
            } else {
                console.error("Netty 服务启动，失败：%s %d", host, PORT);
            }
        });
        closeFuture = channelFuture.channel().closeFuture();
        closeFuture.addListener(future -> {
            if (future.isDone()) {
                console.error("Netty 服务停止：%s %d", host, PORT);
                workerGroup.shutdownGracefully();
                bossGroup.shutdownGracefully();
            }
        });

        return Result.success();
    }
}
